/*
 * File:    Call.java
 * Created: 01-Mar-2009
 * Version: $Id$
 *
 * COPYRIGHT (C) 2009, Bitgate Mobile, LLC.  All Rights Reserved.
 *
 * software@bitgatemobile.com
 */

package com.webplasm.render.tags.u;

import static com.webplasm.render.tags.u.Procedure.PROCEDURE_SCOPE_GLOBAL;
import static com.webplasm.render.tags.u.Procedure.PROCEDURE_SCOPE_LOCAL;

import java.util.Arrays;
import java.util.List;

import com.webplasm.context.RenderContext;
import com.webplasm.render.engine.RenderException;
import com.webplasm.render.tags.TagInterface;
import com.webplasm.render.tags.WrappedNode;
import com.webplasm.render.tags.u.procedure.ProcedureContainer;
import com.webplasm.store.VariableStoreInterface;
import com.webplasm.store.VariableContainer.VariableType;

/**
 * Calls a procedure that is defined either locally or globally.
 * 
 * @author kenji
 * @since Webplasm 1.0
 */
public class Call extends WrappedNode implements TagInterface {
	private static final String DESCRIPTION = "Calls a procedure that was defined either locally or globally.";

	public String getNamespace() {
		return "u";
	}
	
	public List<String> getAttributes() {
		return Arrays.asList("name", "scope");
	}
	
	public List<String> getManagedNodes() {
		return null;
	}

	public String getDescription() {
		return DESCRIPTION;
	}

	@Override
	public StringBuffer render(RenderContext rContext) throws RenderException {
		if (elements.get("name") == null) {
			throw new RenderException("u:call requires a procedure name to be called.");
		}
		
		String procedureScope = elements.get("scope");
		
		if (procedureScope == null) {
			procedureScope = PROCEDURE_SCOPE_LOCAL;
		}
		
		if (procedureScope.equalsIgnoreCase(PROCEDURE_SCOPE_LOCAL)) {
			ProcedureContainer wNodeContainer = rContext.getLocalProcedureStore().getProcedure(elements.get("name"));
			WrappedNode wNode = wNodeContainer.getProcedureNode();
			List<String> procedureVariables = wNodeContainer.getProcedureVariables();
			
			if (wNode != null) {
				RenderContext newContext = new RenderContext(rContext.getClientContext());
				
				for(String varName : procedureVariables) {
					VariableStoreInterface vsInterface = newContext.getVariableStore().getVariable(varName, VariableType.STRING);
					
					vsInterface.setValue(elements.get(varName));
				}
				
				return wNode.render(newContext);
			}
		} else if (procedureScope.equalsIgnoreCase(PROCEDURE_SCOPE_GLOBAL)) {
		} else {
			throw new RenderException("u:call requires a valid scope: local or global");
		}
		
		return new StringBuffer();
	}
}